﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Net;
using System.Drawing;

using MediaPortal.GUI.Library;
using MediaPortal.Dialogs;
using MediaPortal.Util;
using MediaPortal.Configuration;
using MediaPortal.Player;

using Intel.UPNP;
using MediaPortal.Profile;
using System.Windows.Forms;

namespace UPNP_RendererPlugin
{
    
  //[PluginIcons("UPNP_Renderer.renderer200.png", "UPNP_Renderer.renderer200disabled.png")]
    public class UPNP_RendererPlugin : IPlugin, ISetupForm
  {
    private UPnPDevice device;

    private DvAVTransport AVTransport;
    private DvConnectionManager ConnectionManager;
    private DvRenderingControl RenderingControl;

    private bool mediaLoaded = false;
    private string currentTrackMetaData = string.Empty;

    private int currentTrack = 1;
    private int numberOfTracks = 1;

    private string currentTrackURI = string.Empty;
    private string AVTransportURI = string.Empty;

    private string currentPlayState = string.Empty;

    public delegate void CallPlay(string file);
    public delegate void CallStop();
    public delegate void CallPause();

    private bool checkFullscreen;

    private string renderer_name = "not set";
    private string renderer_manufacturer = "not set";
    private string renderer_model = "not set";
    private string renderer_description = "not set";

    private void readMPconfig()
    {
        using (Settings reader = new Settings(Config.GetFile(Config.Dir.Config, "mediaportal.xml")))
        {

            renderer_name = reader.GetValue("upnp_renderer", "renderer_name");
            renderer_manufacturer = reader.GetValue("upnp_renderer", "renderer_manufacturer");
            renderer_model = reader.GetValue("upnp_renderer", "renderer_model");
            renderer_description = reader.GetValue("upnp_renderer", "renderer_description");
            //MessageBox.Show("Einstellungen:" + renderer_name + "\n" + renderer_manufacturer + "\n" + renderer_model + "\n" + renderer_description);
            //MessageBox.Show("");
        }
    }


    public void Start()
    {
       readMPconfig();
       Log.Info("[uPnP Renderer:] Settings read from config!");
       startServer();
       Log.Info("[uPnP Renderer:] Renderer started!");
    }
    public void Stop()
    {
        stopServer();
        Log.Info("[uPnP Renderer:] Renderer stopped!");
    }

    public UPNP_RendererPlugin()
    {

    }

    #region ISetupForm Members

    // Returns the name of the plugin which is shown in the plugin menu 
    public string PluginName()
    {
      return "UPNP Renderer";
    }

    // Returns the description of the plugin is shown in the plugin menu 
    public string Description()
    {
      return "UPNP Browser using Intel's API";
    }

    // Returns the author of the plugin which is shown in the plugin menu 
    public string Author()
    {
      return "Mark Koenig (kroko) 2009 - modified Simon Wüllhorst (cilla) 2010";
    }

    // show the setup dialog 
    public void ShowPlugin()
    {
      // nothing here
        configuration.readMPconfig();
        //string renderer_name = "not set";
        System.Windows.Forms.Form setup = new configuration();
        setup.ShowDialog();
        //new configuration().ShowDialog();
       

    }

    // Indicates whether plugin can be enabled/disabled 
    public bool CanEnable()
    {
      return true;
    }

    // get ID of windowplugin belonging to this setup 
    public int GetWindowId()
    {
        return 45645698;
    }

    // Indicates if plugin is enabled by default; 
    public bool DefaultEnabled()
    {
      return true;
    }

    // indicates if a plugin has its own setup screen 
    public bool HasSetup()
    {
      return true;
    }

    /// <summary> 
    /// If the plugin should have its own button on the main menu of MediaPortal then it 
    /// should return true to this method, otherwise if it should not be on home 
    /// it should return false 
    /// </summary> 
    /// <param name="strButtonText">text the button should have</param> 
    /// <param name="strButtonImage">image for the button, or empty for default</param> 
    /// <param name="strButtonImageFocus">image for the button, or empty for default</param> 
    /// <param name="strPictureImage">subpicture for the button or empty for none</param> 
    /// <returns>true : plugin needs its own button on home 
    /// false : plugin does not need its own button on home</returns> 
    public bool GetHome(out string strButtonText, out string strButtonImage, out string strButtonImageFocus, out string strPictureImage)
    {
      strButtonText = "UPNP Renderer";
      strButtonImage = String.Empty;
      strButtonImageFocus = String.Empty;
      strPictureImage = @"hover_my upnp_renderer.png";
      return true;
    }

    #endregion

    #region Overrides
    /*public override int GetID
    {
      get
      {
        return 45645698;
      }
      set
      {
        base.GetID = value;
      }
    }*/
   /* public override bool Init()
    {
      bool result = Load(GUIGraphicsContext.Skin + @"\MyUPNP_Renderer.xml");
      return result;
    }*/
    private void startServer()
    {
      #region base device declarations
      device = UPnPDevice.CreateRootDevice(1800, 1.0, "\\");
      device.FriendlyName = renderer_name + " (" + System.Windows.Forms.SystemInformation.ComputerName.ToString() + ")";
      device.Manufacturer = renderer_manufacturer;
      device.ManufacturerURL = "http://www.team-mediaportal.com/";
      device.ModelName = renderer_model;
      device.ModelDescription = renderer_description;
      device.ModelNumber = "X1";
      device.ModelURL = new Uri("http://www.team-mediaportal.com/");
      device.HasPresentation = false;
      device.DeviceURN = "urn:schemas-upnp-org:device:MediaRenderer:1";
      device.Icon = new Bitmap(GetEmbeddedResourceStream("UPNP_RendererPlugin.mp.png"));
      #endregion

      #region external declarations
      AVTransport = new DvAVTransport();
      AVTransport.External_GetCurrentTransportActions = new DvAVTransport.Delegate_GetCurrentTransportActions(AVTransport_GetCurrentTransportActions);
      AVTransport.External_GetDeviceCapabilities = new DvAVTransport.Delegate_GetDeviceCapabilities(AVTransport_GetDeviceCapabilities);
      AVTransport.External_GetMediaInfo = new DvAVTransport.Delegate_GetMediaInfo(AVTransport_GetMediaInfo);
      AVTransport.External_GetPositionInfo = new DvAVTransport.Delegate_GetPositionInfo(AVTransport_GetPositionInfo);
      AVTransport.External_GetTransportInfo = new DvAVTransport.Delegate_GetTransportInfo(AVTransport_GetTransportInfo);
      AVTransport.External_GetTransportSettings = new DvAVTransport.Delegate_GetTransportSettings(AVTransport_GetTransportSettings);
      AVTransport.External_Next = new DvAVTransport.Delegate_Next(AVTransport_Next);
      AVTransport.External_Pause = new DvAVTransport.Delegate_Pause(AVTransport_Pause);
      AVTransport.External_Play = new DvAVTransport.Delegate_Play(AVTransport_Play);
      AVTransport.External_Previous = new DvAVTransport.Delegate_Previous(AVTransport_Previous);
      AVTransport.External_Seek = new DvAVTransport.Delegate_Seek(AVTransport_Seek);
      AVTransport.External_SetAVTransportURI = new DvAVTransport.Delegate_SetAVTransportURI(AVTransport_SetAVTransportURI);
      AVTransport.External_SetPlayMode = new DvAVTransport.Delegate_SetPlayMode(AVTransport_SetPlayMode);
      AVTransport.External_Stop = new DvAVTransport.Delegate_Stop(AVTransport_Stop);
      device.AddService(AVTransport);

      ConnectionManager = new DvConnectionManager();
      ConnectionManager.External_GetCurrentConnectionIDs = new DvConnectionManager.Delegate_GetCurrentConnectionIDs(ConnectionManager_GetCurrentConnectionIDs);
      ConnectionManager.External_GetCurrentConnectionInfo = new DvConnectionManager.Delegate_GetCurrentConnectionInfo(ConnectionManager_GetCurrentConnectionInfo);
      ConnectionManager.External_GetProtocolInfo = new DvConnectionManager.Delegate_GetProtocolInfo(ConnectionManager_GetProtocolInfo);
      device.AddService(ConnectionManager);

      RenderingControl = new DvRenderingControl();
      RenderingControl.External_GetBlueVideoBlackLevel = new DvRenderingControl.Delegate_GetBlueVideoBlackLevel(RenderingControl_GetBlueVideoBlackLevel);
      RenderingControl.External_GetBlueVideoGain = new DvRenderingControl.Delegate_GetBlueVideoGain(RenderingControl_GetBlueVideoGain);
      RenderingControl.External_GetBrightness = new DvRenderingControl.Delegate_GetBrightness(RenderingControl_GetBrightness);
      RenderingControl.External_GetColorTemperature = new DvRenderingControl.Delegate_GetColorTemperature(RenderingControl_GetColorTemperature);
      RenderingControl.External_GetContrast = new DvRenderingControl.Delegate_GetContrast(RenderingControl_GetContrast);
      RenderingControl.External_GetGreenVideoBlackLevel = new DvRenderingControl.Delegate_GetGreenVideoBlackLevel(RenderingControl_GetGreenVideoBlackLevel);
      RenderingControl.External_GetGreenVideoGain = new DvRenderingControl.Delegate_GetGreenVideoGain(RenderingControl_GetGreenVideoGain);
      RenderingControl.External_GetHorizontalKeystone = new DvRenderingControl.Delegate_GetHorizontalKeystone(RenderingControl_GetHorizontalKeystone);
      RenderingControl.External_GetLoudness = new DvRenderingControl.Delegate_GetLoudness(RenderingControl_GetLoudness);
      RenderingControl.External_GetMute = new DvRenderingControl.Delegate_GetMute(RenderingControl_GetMute);
      RenderingControl.External_GetRedVideoBlackLevel = new DvRenderingControl.Delegate_GetRedVideoBlackLevel(RenderingControl_GetRedVideoBlackLevel);
      RenderingControl.External_GetRedVideoGain = new DvRenderingControl.Delegate_GetRedVideoGain(RenderingControl_GetRedVideoGain);
      RenderingControl.External_GetSharpness = new DvRenderingControl.Delegate_GetSharpness(RenderingControl_GetSharpness);
      RenderingControl.External_GetVerticalKeystone = new DvRenderingControl.Delegate_GetVerticalKeystone(RenderingControl_GetVerticalKeystone);
      RenderingControl.External_GetVolume = new DvRenderingControl.Delegate_GetVolume(RenderingControl_GetVolume);
      RenderingControl.External_ListPresets = new DvRenderingControl.Delegate_ListPresets(RenderingControl_ListPresets);
      RenderingControl.External_SelectPreset = new DvRenderingControl.Delegate_SelectPreset(RenderingControl_SelectPreset);
      RenderingControl.External_SetBlueVideoBlackLevel = new DvRenderingControl.Delegate_SetBlueVideoBlackLevel(RenderingControl_SetBlueVideoBlackLevel);
      RenderingControl.External_SetBlueVideoGain = new DvRenderingControl.Delegate_SetBlueVideoGain(RenderingControl_SetBlueVideoGain);
      RenderingControl.External_SetBrightness = new DvRenderingControl.Delegate_SetBrightness(RenderingControl_SetBrightness);
      RenderingControl.External_SetColorTemperature = new DvRenderingControl.Delegate_SetColorTemperature(RenderingControl_SetColorTemperature);
      RenderingControl.External_SetContrast = new DvRenderingControl.Delegate_SetContrast(RenderingControl_SetContrast);
      RenderingControl.External_SetGreenVideoBlackLevel = new DvRenderingControl.Delegate_SetGreenVideoBlackLevel(RenderingControl_SetGreenVideoBlackLevel);
      RenderingControl.External_SetGreenVideoGain = new DvRenderingControl.Delegate_SetGreenVideoGain(RenderingControl_SetGreenVideoGain);
      RenderingControl.External_SetHorizontalKeystone = new DvRenderingControl.Delegate_SetHorizontalKeystone(RenderingControl_SetHorizontalKeystone);
      RenderingControl.External_SetLoudness = new DvRenderingControl.Delegate_SetLoudness(RenderingControl_SetLoudness);
      RenderingControl.External_SetMute = new DvRenderingControl.Delegate_SetMute(RenderingControl_SetMute);
      RenderingControl.External_SetRedVideoBlackLevel = new DvRenderingControl.Delegate_SetRedVideoBlackLevel(RenderingControl_SetRedVideoBlackLevel);
      RenderingControl.External_SetRedVideoGain = new DvRenderingControl.Delegate_SetRedVideoGain(RenderingControl_SetRedVideoGain);
      RenderingControl.External_SetSharpness = new DvRenderingControl.Delegate_SetSharpness(RenderingControl_SetSharpness);
      RenderingControl.External_SetVerticalKeystone = new DvRenderingControl.Delegate_SetVerticalKeystone(RenderingControl_SetVerticalKeystone);
      RenderingControl.External_SetVolume = new DvRenderingControl.Delegate_SetVolume(RenderingControl_SetVolume);
      device.AddService(RenderingControl);

      #endregion

      // Setting the initial value of evented variables
      AVTransport.Evented_LastChange = "&lt;Event xmlns=\"urn:schemas-upnp-org:metadata-1-0/AVT/\"/ &gt;";

      // needed for type compare
      ConnectionManager.Evented_SinkProtocolInfo = "http-get:*:audio/flac:*,http-get:*:audio/mpegurl:*,http-get:*:audio/x-mpegurl:*,http-get:*:audio/mp3:*,http-get:*:audio/mpeg:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wma:*,http-get:*:audio/mpeg3:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/x-ms-asf:*,http-get:*:video/x-ms-avi:*,http-get:*:video/mpeg:*,http-get:*:video/x-msvideo:*";
      ConnectionManager.Evented_SourceProtocolInfo = "";
      ConnectionManager.Evented_CurrentConnectionIDs = "0";

      // send volume level
      string rcs = "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/RCS/\"&gt;\n";
      rcs += "&lt;InstanceID val=\"0\"&gt;\n";
      rcs += "&lt;Volume val=\"100\" channel=\"LF\"/&gt;\n";
      rcs += "&lt;Volume val=\"100\" channel=\"RF\"/&gt;\n";
      rcs += "&lt;/InstanceID&gt;\n";
      rcs += "&lt;/Event&gt;";
      RenderingControl.Evented_LastChange = rcs;

      device.StartDevice();
      //base.OnPageLoad();
    }
    private void stopServer()
    {
      device.StopDevice();
    }
    /*protected override void OnClicked(int controlId, GUIControl control, MediaPortal.GUI.Library.Action.ActionType actionType)
    {
      base.OnClicked(controlId, control, actionType);
    }*/
    #endregion

    // here we arange the data from vlc as info and receive the links
    public void AVTransport_GetCurrentTransportActions(System.UInt32 InstanceID, out System.String Actions)
    {
      string posibleActions = "";

      if (mediaLoaded)
      {
        posibleActions += "Play";
        if (g_Player.Playing)
        {
          posibleActions += ",Stop";
          if (g_Player.Playing) posibleActions += ",Pause";
          if (numberOfTracks > 1)
          {
            posibleActions += ",Next";
            posibleActions += ",Previous";
          }
        }
      }
      Actions = posibleActions;
      System.Diagnostics.Debug.WriteLine("AVTransport_GetCurrentTransportActions(" + InstanceID.ToString() + ")");
    }
    public void AVTransport_GetDeviceCapabilities(System.UInt32 InstanceID, out System.String PlayMedia, out System.String RecMedia, out System.String RecQualityModes)
    {
      // take from intel device

      PlayMedia = "vendor-defined ,NOT_IMPLEMENTED,NONE,NETWORK,MICRO-MV,HDD,LD,DAT,DVD-AUDIO,DVD-RAM,DVD-RW,DVD+RW,DVD-R,DVD-VIDEO,DVD-ROM,MD-PICTURE,MD-AUDIO,SACD,VIDEO-CD,CD-RW,CD-R,CD-DA,CD-ROM,HI8,VIDEO8,VHSC,D-VHS,S-VHS,W-VHS,VHS,MINI-DV,DV,UNKNOWN";
      RecMedia = "vendor-defined ,NOT_IMPLEMENTED,NONE,NETWORK,MICRO-MV,HDD,LD,DAT,DVD-AUDIO,DVD-RAM,DVD-RW,DVD+RW,DVD-R,DVD-VIDEO,DVD-ROM,MD-PICTURE,MD-AUDIO,SACD,VIDEO-CD,CD-RW,CD-R,CD-DA,CD-ROM,HI8,VIDEO8,VHSC,D-VHS,S-VHS,W-VHS,VHS,MINI-DV,DV,UNKNOWN";
      RecQualityModes = "vendor-defined ,NOT_IMPLEMENTED,2:HIGH,1:MEDIUM,0:BASIC,2:SP,1:LP,0:EP";

      System.Diagnostics.Debug.WriteLine("AVTransport_GetDeviceCapabilities(" + InstanceID.ToString() + ")");
    }
    public void AVTransport_GetMediaInfo(System.UInt32 InstanceID, out System.UInt32 NrTracks, out System.String MediaDuration, out System.String CurrentURI, out System.String CurrentURIMetaData, out System.String NextURI, out System.String NextURIMetaData, out DvAVTransport.Enum_PlaybackStorageMedium PlayMedium, out DvAVTransport.Enum_RecordStorageMedium RecordMedium, out DvAVTransport.Enum_RecordMediumWriteStatus WriteStatus)
    {
      NrTracks = (uint)numberOfTracks;
      MediaDuration = "Sample String";
      CurrentURI = currentTrackURI;
      CurrentURIMetaData = currentTrackMetaData;
      NextURI = "UNKNOWN";
      NextURIMetaData = "UNKNOWN";

      PlayMedium = DvAVTransport.Enum_PlaybackStorageMedium.UNKNOWN;
      RecordMedium = DvAVTransport.Enum_RecordStorageMedium.UNKNOWN;
      WriteStatus = DvAVTransport.Enum_RecordMediumWriteStatus.WRITABLE;
      System.Diagnostics.Debug.WriteLine("AVTransport_GetMediaInfo(" + InstanceID.ToString() + ")");
    }
    public void AVTransport_GetPositionInfo(System.UInt32 InstanceID, out System.UInt32 Track, out System.String TrackDuration, out System.String TrackMetaData, out System.String TrackURI, out System.String RelTime, out System.String AbsTime, out System.Int32 RelCount, out System.Int32 AbsCount)
    {
      //System.Diagnostics.Debug.WriteLine("AVTransport_GetPositionInfo(" + InstanceID.ToString() + ")");

      Track = (uint)currentTrack;

      DateTime dt = new DateTime();
      dt = dt.AddSeconds(g_Player.Duration);

      TrackDuration = string.Format("{0:00}", dt.Hour) + ":" + string.Format("{0:00}", dt.Minute) + ":" + string.Format("{0:00}", dt.Second);

      TrackMetaData = "Sample String";
      TrackURI = "Sample String";

      dt = new DateTime();
      dt = dt.AddSeconds(g_Player.CurrentPosition);

      RelTime = string.Format("{0:00}", dt.Hour) + ":" + string.Format("{0:00}", dt.Minute) + ":" + string.Format("{0:00}", dt.Second);

      AbsTime = "Sample String";
      RelCount = 0;
      AbsCount = 0;

      if ((checkFullscreen) && (g_Player.CurrentPosition > 9))
      {
        checkFullscreen = false;
        if (g_Player.HasVideo) g_Player.FullScreen = true;
      }

    }
    public void AVTransport_GetTransportInfo(System.UInt32 InstanceID, out DvAVTransport.Enum_TransportState CurrentTransportState, out DvAVTransport.Enum_TransportStatus CurrentTransportStatus, out DvAVTransport.Enum_TransportPlaySpeed CurrentSpeed)
    {
      CurrentTransportState = DvAVTransport.Enum_TransportState.STOPPED;
      CurrentTransportStatus = DvAVTransport.Enum_TransportStatus.OK;
      CurrentSpeed = DvAVTransport.Enum_TransportPlaySpeed._1;
      System.Diagnostics.Debug.WriteLine("AVTransport_GetTransportInfo(" + InstanceID.ToString() + ")");
    }
    public void AVTransport_GetTransportSettings(System.UInt32 InstanceID, out DvAVTransport.Enum_CurrentPlayMode PlayMode, out DvAVTransport.Enum_CurrentRecordQualityMode RecQualityMode)
    {
      PlayMode = DvAVTransport.Enum_CurrentPlayMode.NORMAL;
      RecQualityMode = DvAVTransport.Enum_CurrentRecordQualityMode._0_EP;
      System.Diagnostics.Debug.WriteLine("AVTransport_GetTransportSettings(" + InstanceID.ToString() + ")");
    }
    public void AVTransport_Next(System.UInt32 InstanceID)
    {
      System.Diagnostics.Debug.WriteLine("AVTransport_Next(" + InstanceID.ToString() + ")");
      if (currentTrack < numberOfTracks)
      {
        currentTrack++;

        playListItem actual = playList[currentTrack];
        currentTrackURI = actual.url;

        string rcs = "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/AVT/\"&gt;\n";
        rcs += "&lt;InstanceID val=\"0\"&gt;\n";
        rcs += "&lt;AVTransportURI val=\"" + actual.url + "\"/&gt;\n";
        rcs += "&lt;/InstanceID&gt;\n";
        rcs += "&lt;/Event&gt;";
        AVTransport.Evented_LastChange = rcs;

        rcs = "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/AVT/\"&gt;\n";
        rcs += "&lt;InstanceID val=\"0\"&gt;\n";
        rcs += "&lt;NumberOfTracks val=\"" + numberOfTracks + "\"/&gt;\n";
        rcs += "&lt;CurrentTrack val=\"" + currentTrack + "\"/&gt;\n";
        rcs += "&lt;/InstanceID&gt;\n";
        rcs += "&lt;/Event&gt;";
        AVTransport.Evented_LastChange = rcs;
      }
    }
    public void AVTransport_Pause(System.UInt32 InstanceID)
    {
      System.Diagnostics.Debug.WriteLine("AVTransport_Pause(" + InstanceID.ToString() + ")");

      CallPause d = new CallPause(VLCPAUSE); // a new delgate
      GUIGraphicsContext.form.Invoke(d, new object[] { }); // call through right thread
    }
    public void AVTransport_Play(System.UInt32 InstanceID, DvAVTransport.Enum_TransportPlaySpeed Speed)
    {
      System.Diagnostics.Debug.WriteLine("AVTransport_Play(" + InstanceID.ToString() + Speed.ToString() + ")");

      CallPlay d = new CallPlay(VLCPLAY); // a new delgate
      GUIGraphicsContext.form.Invoke(d, new object[] { currentTrackURI }); // call through right thread

      checkFullscreen = true;
    }
    public void AVTransport_Previous(System.UInt32 InstanceID)
    {
      System.Diagnostics.Debug.WriteLine("AVTransport_Previous(" + InstanceID.ToString() + ")");
      if (currentTrack > 1)
      {
        currentTrack--;

        playListItem actual = playList[currentTrack];
        currentTrackURI = actual.url;

        string rcs = "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/AVT/\"&gt;\n";
        rcs += "&lt;InstanceID val=\"0\"&gt;\n";
        rcs += "&lt;AVTransportURI val=\"" + actual.url + "\"/&gt;\n";
        rcs += "&lt;/InstanceID&gt;\n";
        rcs += "&lt;/Event&gt;";
        AVTransport.Evented_LastChange = rcs;

        rcs = "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/AVT/\"&gt;\n";
        rcs += "&lt;InstanceID val=\"0\"&gt;\n";
        rcs += "&lt;NumberOfTracks val=\"" + numberOfTracks + "\"/&gt;\n";
        rcs += "&lt;CurrentTrack val=\"" + currentTrack + "\"/&gt;\n";
        rcs += "&lt;/InstanceID&gt;\n";
        rcs += "&lt;/Event&gt;";
        AVTransport.Evented_LastChange = rcs;
      }
    }
    public void AVTransport_Seek(System.UInt32 InstanceID, DvAVTransport.Enum_A_ARG_TYPE_SeekMode Unit, System.String Target)
    {
      System.Diagnostics.Debug.WriteLine("AVTransport_Seek(" + InstanceID.ToString() + Unit.ToString() + Target.ToString() + ")");
    }
    public void AVTransport_SetAVTransportURI(System.UInt32 InstanceID, System.String CurrentURI, System.String CurrentURIMetaData)
    {
      System.Diagnostics.Debug.WriteLine("AVTransport_SetAVTransportURI(" + InstanceID.ToString() + CurrentURI.ToString() + CurrentURIMetaData.ToString() + ")");
      AVTransportURI = CurrentURI;

      currentTrackMetaData = CurrentURIMetaData.ToString();

      //g_Player.Init();
      //g_Player.Stop(); // just in case

      actualPlayListItem = 1;

      playList = new List<playListItem>();
      if (CurrentURI.ToLower().EndsWith("m3u"))
      {
        playList = readM3UCurrentURI(CurrentURI);
      }
      else
      {
        playListItem item = new playListItem();
        item.title = "unknown item no. " + (playList.Count + 1).ToString();
        item.url = CurrentURI;
        playList.Add(item);
      }

      numberOfTracks = playList.Count;

      if (playList.Count > 0)
      {

        playListItem actual = playList[0];
        currentTrackURI = actual.url;

        currentTrack = 1;

        string rcs = "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/AVT/\"&gt;\n";
        rcs += "&lt;InstanceID val=\"0\"&gt;\n";
        rcs += "&lt;AVTransportURI val=\"" + actual.url + "\"/&gt;\n";
        rcs += "&lt;/InstanceID&gt;\n";
        rcs += "&lt;/Event&gt;";
        AVTransport.Evented_LastChange = rcs;

        rcs = "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/AVT/\"&gt;\n";
        rcs += "&lt;InstanceID val=\"0\"&gt;\n";
        rcs += "&lt;NumberOfTracks val=\"" + numberOfTracks + "\"/&gt;\n";
        rcs += "&lt;CurrentTrack val=\"" + currentTrack + "\"/&gt;\n";
        rcs += "&lt;/InstanceID&gt;\n";
        rcs += "&lt;/Event&gt;";
        AVTransport.Evented_LastChange = rcs;

        mediaLoaded = true;
      }
    }
    public void AVTransport_SetPlayMode(System.UInt32 InstanceID, DvAVTransport.Enum_CurrentPlayMode NewPlayMode)
    {
      System.Diagnostics.Debug.WriteLine("AVTransport_SetPlayMode(" + InstanceID.ToString() + NewPlayMode.ToString() + ")");
    }
    public void AVTransport_Stop(System.UInt32 InstanceID)
    {
      System.Diagnostics.Debug.WriteLine("AVTransport_Stop(" + InstanceID.ToString() + ")");

      CallStop d = new CallStop(VLCSTOP); // a new delgate
      GUIGraphicsContext.form.Invoke(d, new object[] { }); // call through right thread
    }

    // mostly could be ignored
    public void ConnectionManager_GetCurrentConnectionIDs(out System.String ConnectionIDs)
    {
      ConnectionIDs = "0";
      System.Diagnostics.Debug.WriteLine("ConnectionManager_GetCurrentConnectionIDs(" + ")");
    }
    public void ConnectionManager_GetCurrentConnectionInfo(System.Int32 ConnectionID, out System.Int32 RcsID, out System.Int32 AVTransportID, out System.String ProtocolInfo, out System.String PeerConnectionManager, out System.Int32 PeerConnectionID, out DvConnectionManager.Enum_A_ARG_TYPE_Direction Direction, out DvConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus Status)
    {
      RcsID = 0;
      AVTransportID = 0;
      ProtocolInfo = ":::";
      PeerConnectionManager = "/";
      PeerConnectionID = 0;
      Direction = DvConnectionManager.Enum_A_ARG_TYPE_Direction.INPUT;
      Status = DvConnectionManager.Enum_A_ARG_TYPE_ConnectionStatus.OK;
      System.Diagnostics.Debug.WriteLine("ConnectionManager_GetCurrentConnectionInfo(" + ConnectionID.ToString() + ")");
    }
    public void ConnectionManager_GetProtocolInfo(out System.String Source, out System.String Sink)
    {
      Source = "";
      Sink = "http-get:*:audio/flac:*,http-get:*:audio/mpegurl:*,http-get:*:audio/mp3:*,http-get:*:audio/mpeg:*,http-get:*:audio/x-ms-wma:*,http-get:*:audio/wma:*,http-get:*:audio/mpeg3:*,http-get:*:video/x-ms-wmv:*,http-get:*:video/x-ms-asf:*,http-get:*:video/x-ms-avi:*,http-get:*:video/mpeg:*,http-get:*:video/x-msvideo:*";
      System.Diagnostics.Debug.WriteLine("ConnectionManager_GetProtocolInfo(" + ")");
    }

    // so far only volume and mute is supported
    public void RenderingControl_GetBlueVideoBlackLevel(System.UInt32 InstanceID, out System.UInt16 CurrentBlueVideoBlackLevel)
    {
      CurrentBlueVideoBlackLevel = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetBlueVideoBlackLevel(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetBlueVideoGain(System.UInt32 InstanceID, out System.UInt16 CurrentBlueVideoGain)
    {
      CurrentBlueVideoGain = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetBlueVideoGain(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetBrightness(System.UInt32 InstanceID, out System.UInt16 CurrentBrightness)
    {
      CurrentBrightness = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetBrightness(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetColorTemperature(System.UInt32 InstanceID, out System.UInt16 CurrentColorTemperature)
    {
      CurrentColorTemperature = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetColorTemperature(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetContrast(System.UInt32 InstanceID, out System.UInt16 CurrentContrast)
    {
      CurrentContrast = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetContrast(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetGreenVideoBlackLevel(System.UInt32 InstanceID, out System.UInt16 CurrentGreenVideoBlackLevel)
    {
      CurrentGreenVideoBlackLevel = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetGreenVideoBlackLevel(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetGreenVideoGain(System.UInt32 InstanceID, out System.UInt16 CurrentGreenVideoGain)
    {
      CurrentGreenVideoGain = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetGreenVideoGain(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetHorizontalKeystone(System.UInt32 InstanceID, out System.Int16 CurrentHorizontalKeystone)
    {
      CurrentHorizontalKeystone = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetHorizontalKeystone(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetLoudness(System.UInt32 InstanceID, DvRenderingControl.Enum_A_ARG_TYPE_Channel Channel, out System.Boolean CurrentLoudness)
    {
      CurrentLoudness = false;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetLoudness(" + InstanceID.ToString() + Channel.ToString() + ")");
    }
    public void RenderingControl_GetMute(System.UInt32 InstanceID, DvRenderingControl.Enum_A_ARG_TYPE_Channel Channel, out System.Boolean CurrentMute)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetMute(" + InstanceID.ToString() + Channel.ToString() + ")");
      CurrentMute = false;

      // we just support master volume here
      switch (Channel)
      {
        case DvRenderingControl.Enum_A_ARG_TYPE_Channel.MASTER:
          VolumeHandler volume = VolumeHandler.Instance;
          CurrentMute = volume.IsMuted;
          break;
        case DvRenderingControl.Enum_A_ARG_TYPE_Channel.LF:
          break;
        case DvRenderingControl.Enum_A_ARG_TYPE_Channel.RF:
          break;
      }

    }
    public void RenderingControl_GetRedVideoBlackLevel(System.UInt32 InstanceID, out System.UInt16 CurrentRedVideoBlackLevel)
    {
      CurrentRedVideoBlackLevel = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetRedVideoBlackLevel(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetRedVideoGain(System.UInt32 InstanceID, out System.UInt16 CurrentRedVideoGain)
    {
      CurrentRedVideoGain = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetRedVideoGain(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetSharpness(System.UInt32 InstanceID, out System.UInt16 CurrentSharpness)
    {
      CurrentSharpness = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetSharpness(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetVerticalKeystone(System.UInt32 InstanceID, out System.Int16 CurrentVerticalKeystone)
    {
      CurrentVerticalKeystone = 0;
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetVerticalKeystone(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_GetVolume(System.UInt32 InstanceID, DvRenderingControl.Enum_A_ARG_TYPE_Channel Channel, out System.UInt16 CurrentVolume)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_GetVolume(" + InstanceID.ToString() + Channel.ToString() + ")");
      CurrentVolume = 100;

      // we just support master volume here
      switch (Channel)
      {
        case DvRenderingControl.Enum_A_ARG_TYPE_Channel.MASTER:
          VolumeHandler volume = VolumeHandler.Instance;
          int x = volume.Volume / volume.Maximum * 100;
          CurrentVolume = (ushort)x;
          break;
        case DvRenderingControl.Enum_A_ARG_TYPE_Channel.LF:
          break;
        case DvRenderingControl.Enum_A_ARG_TYPE_Channel.RF:
          break;
      }

    }
    public void RenderingControl_ListPresets(System.UInt32 InstanceID, out System.String CurrentPresetNameList)
    {
      CurrentPresetNameList = "Sample String";
      System.Diagnostics.Debug.WriteLine("RenderingControl_ListPresets(" + InstanceID.ToString() + ")");
    }
    public void RenderingControl_SelectPreset(System.UInt32 InstanceID, DvRenderingControl.Enum_A_ARG_TYPE_PresetName PresetName)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SelectPreset(" + InstanceID.ToString() + PresetName.ToString() + ")");
    }
    public void RenderingControl_SetBlueVideoBlackLevel(System.UInt32 InstanceID, System.UInt16 DesiredBlueVideoBlackLevel)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetBlueVideoBlackLevel(" + InstanceID.ToString() + DesiredBlueVideoBlackLevel.ToString() + ")");
    }
    public void RenderingControl_SetBlueVideoGain(System.UInt32 InstanceID, System.UInt16 DesiredBlueVideoGain)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetBlueVideoGain(" + InstanceID.ToString() + DesiredBlueVideoGain.ToString() + ")");
    }
    public void RenderingControl_SetBrightness(System.UInt32 InstanceID, System.UInt16 DesiredBrightness)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetBrightness(" + InstanceID.ToString() + DesiredBrightness.ToString() + ")");
    }
    public void RenderingControl_SetColorTemperature(System.UInt32 InstanceID, System.UInt16 DesiredColorTemperature)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetColorTemperature(" + InstanceID.ToString() + DesiredColorTemperature.ToString() + ")");
    }
    public void RenderingControl_SetContrast(System.UInt32 InstanceID, System.UInt16 DesiredContrast)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetContrast(" + InstanceID.ToString() + DesiredContrast.ToString() + ")");
    }
    public void RenderingControl_SetGreenVideoBlackLevel(System.UInt32 InstanceID, System.UInt16 DesiredGreenVideoBlackLevel)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetGreenVideoBlackLevel(" + InstanceID.ToString() + DesiredGreenVideoBlackLevel.ToString() + ")");
    }
    public void RenderingControl_SetGreenVideoGain(System.UInt32 InstanceID, System.UInt16 DesiredGreenVideoGain)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetGreenVideoGain(" + InstanceID.ToString() + DesiredGreenVideoGain.ToString() + ")");
    }
    public void RenderingControl_SetHorizontalKeystone(System.UInt32 InstanceID, System.Int16 DesiredHorizontalKeystone)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetHorizontalKeystone(" + InstanceID.ToString() + DesiredHorizontalKeystone.ToString() + ")");
    }
    public void RenderingControl_SetLoudness(System.UInt32 InstanceID, DvRenderingControl.Enum_A_ARG_TYPE_Channel Channel, System.Boolean DesiredLoudness)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetLoudness(" + InstanceID.ToString() + Channel.ToString() + DesiredLoudness.ToString() + ")");
    }
    public void RenderingControl_SetMute(System.UInt32 InstanceID, DvRenderingControl.Enum_A_ARG_TYPE_Channel Channel, System.Boolean DesiredMute)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetMute(" + InstanceID.ToString() + Channel.ToString() + DesiredMute.ToString() + ")");
      if (Channel == DvRenderingControl.Enum_A_ARG_TYPE_Channel.MASTER)
      {
        VolumeHandler volume = VolumeHandler.Instance;
        volume.IsMuted = DesiredMute;
        string rcs = "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/RCS/\"&gt;\n";

        rcs += "&lt;InstanceID val=\"0\"&gt;\n";
        rcs += "&lt;Mute channel=\"Master\" val=\"" + DesiredMute.ToString().ToLower() + "\"/&gt;\n";
        rcs += "&lt;/InstanceID&gt;\n";
        rcs += "&lt;/Event&gt;";

        RenderingControl.Evented_LastChange = rcs;
      }
    }
    public void RenderingControl_SetRedVideoBlackLevel(System.UInt32 InstanceID, System.UInt16 DesiredRedVideoBlackLevel)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetRedVideoBlackLevel(" + InstanceID.ToString() + DesiredRedVideoBlackLevel.ToString() + ")");
    }
    public void RenderingControl_SetRedVideoGain(System.UInt32 InstanceID, System.UInt16 DesiredRedVideoGain)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetRedVideoGain(" + InstanceID.ToString() + DesiredRedVideoGain.ToString() + ")");
    }
    public void RenderingControl_SetSharpness(System.UInt32 InstanceID, System.UInt16 DesiredSharpness)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetSharpness(" + InstanceID.ToString() + DesiredSharpness.ToString() + ")");
    }
    public void RenderingControl_SetVerticalKeystone(System.UInt32 InstanceID, System.Int16 DesiredVerticalKeystone)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetVerticalKeystone(" + InstanceID.ToString() + DesiredVerticalKeystone.ToString() + ")");
    }
    public void RenderingControl_SetVolume(System.UInt32 InstanceID, DvRenderingControl.Enum_A_ARG_TYPE_Channel Channel, System.UInt16 DesiredVolume)
    {
      System.Diagnostics.Debug.WriteLine("RenderingControl_SetVolume(" + InstanceID.ToString() + Channel.ToString() + DesiredVolume.ToString() + ")");
      if (Channel == DvRenderingControl.Enum_A_ARG_TYPE_Channel.MASTER)
      {
        VolumeHandler volume = VolumeHandler.Instance;
        int x = volume.Maximum * DesiredVolume / 100;
        volume.Volume = x;

        string rcs = "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/RCS/\"&gt;\n";

        rcs += "&lt;InstanceID val=\"0\"&gt;\n";
        rcs += "&lt;Volume val=\"" + DesiredVolume.ToString() + "\" channel=\"MASTER\"/&gt;\n";
        rcs += "&lt;/InstanceID&gt;\n";
        rcs += "&lt;/Event&gt;";

        RenderingControl.Evented_LastChange = rcs;
      }
    }

    // vlc stuff

    private void VLCPLAY(string file)
    {
      g_Player.PlayBackStarted -= new g_Player.StartedHandler(g_Player_PlayBackStarted);
      g_Player.PlayBackStarted += new g_Player.StartedHandler(g_Player_PlayBackStarted);

      g_Player.PlayBackEnded -= new g_Player.EndedHandler(g_Player_PlayBackEnded);
      g_Player.PlayBackEnded += new g_Player.EndedHandler(g_Player_PlayBackEnded);

      g_Player.PlayBackStopped -= new g_Player.StoppedHandler(g_Player_PlayBackStopped);
      g_Player.PlayBackStopped += new g_Player.StoppedHandler(g_Player_PlayBackStopped);
      g_Player.Play(currentTrackURI);
      //g_Player.PlayVideoStream(currentTrackURI);
      //g_Player.Play(currentTrackURI, g_Player.MediaType.Video);
    }

    private void VLCSTOP()
    {
      g_Player.Stop();
    }
    private void VLCPAUSE()
    {
      g_Player.Pause();
      if (g_Player.Paused)
        currentPlayState = "PAUSED_PLAYBACK";
      if (!g_Player.Paused)
        currentPlayState = "PLAYING";
      StateChanged();
    }

    // events
    // make states like STOPPED, PAUSED_PLAYBACK, PAUSED_RECORDING, PLAYING, RECORDING, TRANSITIONING, NO_MEDIA_PRESENT


    void g_Player_PlayBackStarted(g_Player.MediaType type, string filename)
    {
      System.Diagnostics.Debug.WriteLine("UPNP Renderer : Play started");

      currentPlayState = "PLAYING";
      StateChanged();
    }
    void g_Player_PlayBackEnded(g_Player.MediaType type, string filename)
    {
      System.Diagnostics.Debug.WriteLine("UPNP Renderer : Play ended");

      currentPlayState = "STOPPED";
      StateChanged();
    }
    void g_Player_PlayBackStopped(g_Player.MediaType type, int stoptime, string filename)
    {
      System.Diagnostics.Debug.WriteLine("UPNP Renderer : Play stopped");
      currentPlayState = "STOPPED";
      StateChanged();
    }

    private void StateChanged()
    {
      System.Diagnostics.Debug.WriteLine("UPNP Renderer : state changed : " + currentPlayState);

      string avt = string.Empty;

      avt += "&lt;Event xmlns = \"urn:schemas-upnp-org:metadata-1-0/AVT/\"&gt;\n";
      avt += "&lt;InstanceID val=\"0\"&gt;\n";

      avt += "&lt;TransportState val=\"" + currentPlayState + "\"/&gt;\n";

      avt += "&lt;/InstanceID&gt;\n";
      avt += "&lt;/Event&gt;";
      AVTransport.Evented_LastChange = avt;
    }


    // helper
    protected Stream GetEmbeddedResourceStream(string ResourceName)
    {
      return System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(ResourceName);
    }

    // playlist helper
    private class playListItem
    {
      public string title = string.Empty;
      public string url = string.Empty;
    }
    private List<playListItem> playList;
    private int actualPlayListItem = 1;

    private List<playListItem> readM3UCurrentURI(string M3U)
    {
      List<playListItem> playlist = new List<playListItem>();
      string list = string.Empty;

      try
      {
        WebClient client = new WebClient();
        byte[] data = client.DownloadData(M3U);
        list = Encoding.ASCII.GetString(data);
      }
      catch
      {
        // no file ???
      }

      string[] lines = list.Split('\n');
      if (lines != null)
      {
        if (lines.Length > 0)
        {
          playListItem item = new playListItem();

          for (int i = 1; i < lines.Length; i++)
          {
            lines[i] = lines[i].Replace("\r", "");
            if (lines[i].StartsWith("#EXTINF:"))
            {
              string s = lines[i].Substring(8);
              item.title = s.Split(',')[1];
            }
            else if (!lines[i].StartsWith("#"))
            {
              item.url = lines[i];
              playlist.Add(item);

              item = new playListItem();
            }
          }
        }
      }



      return playlist;
    }

    public string CurrentMetaData
    {
      get { return currentTrackMetaData; }
      set { currentTrackMetaData = value; }
    }


  }
}
